package org.gdstash.ui;

import org.gdstash.db.SelectionCriteria;
import org.gdstash.ui.select.*;
import org.gdstash.util.GDImagePool;
import org.gdstash.util.GDLog;
import org.gdstash.util.GDMsgFormatter;
import org.gdstash.util.GDMsgLogger;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class GDTabbedSearchDialog extends JDialog {
    private Component owner;
    private JButton btnSearch;
    private JButton btnClear;
    private SelectAndOrPane pnlAndOr;
    private GDUISearch uiSearch;
    private JTabbedPane pnlTabbed;
    private ItemFullSelectionPane pnlItem;
    private DamageSelectionPane pnlDamage;
    private AttribSelectionPane pnlAttrib;
    private SkillBonusPane pnlBonusSkill;
    private SkillModifierPane pnlModifiedSkill;
    private ItemSkillPane pnlItemSkill;
    private AffixPane pnlAffix;
    private SelectionCriteria.SoulboundMode soulboundDefault;
    private boolean soulboundEnabled;
    private Mode mode;

    public GDTabbedSearchDialog(final Frame owner, final GDUISearch uiSearch, final Mode mode) {
        this(owner, uiSearch, mode, true, SelectionCriteria.SoulboundMode.ALL, true);
    }

    public GDTabbedSearchDialog(final Frame owner, final GDUISearch uiSearch, final Mode mode, final SelectionCriteria.SoulboundMode soulboundDefault) {
        this(owner, uiSearch, mode, true, soulboundDefault, true);
    }

    public GDTabbedSearchDialog(final Frame owner, final GDUISearch uiSearch, final Mode mode, final SelectionCriteria.SoulboundMode soulboundDefault, final boolean soulboundEnabled) {
        this(owner, uiSearch, mode, true, soulboundDefault, soulboundEnabled);
    }

    public GDTabbedSearchDialog(final Frame owner, final GDUISearch uiSearch, final Mode mode, final boolean modal, final SelectionCriteria.SoulboundMode soulboundDefault, final boolean soulboundEnabled) {
        super(owner, modal);
        this.owner = owner;
        this.uiSearch = uiSearch;
        this.soulboundDefault = soulboundDefault;
        this.soulboundEnabled = soulboundEnabled;
        this.mode = mode;
        this.adjustUI();
        final JPanel pnlMain = this.buildMainPanel();
        this.getContentPane().add(pnlMain);
        this.pack();
        this.setLocationRelativeTo(owner);
        this.getRootPane().registerKeyboardAction(new CloseActionListener(), KeyStroke.getKeyStroke(27, 0), 2);
        this.getRootPane().setDefaultButton(this.btnSearch);
        this.btnSearch.requestFocus();
    }

    public void adjustUI() {
        this.setTitle(GDMsgFormatter.getString(GDMsgFormatter.rbUI, "BTN_SEARCH"));
        final Font fntLabel = UIManager.getDefaults().getFont("Label.font");
        Font fntButton = UIManager.getDefaults().getFont("Button.font");
        if (fntButton == null) {
            fntButton = fntLabel;
        }
        fntButton = fntButton.deriveFont((float) GDStashFrame.iniConfig.sectUI.fontSize);
        if (this.btnSearch == null) {
            (this.btnSearch = new JButton()).addActionListener(new SearchActionListener());
        }
        this.btnSearch.setText(GDMsgFormatter.getString(GDMsgFormatter.rbUI, "BTN_SEARCH"));
        this.btnSearch.setIcon(GDImagePool.iconBtnSearch24);
        this.btnSearch.setFont(fntButton);
        GDStashFrame.setMnemonic(this.btnSearch, "MNC_SEARCH");
        if (this.btnClear == null) {
            (this.btnClear = new JButton()).addActionListener(new ClearActionListener());
        }
        this.btnClear.setText(GDMsgFormatter.getString(GDMsgFormatter.rbUI, "BTN_CLEAR"));
        this.btnClear.setIcon(GDImagePool.iconItemDelete24);
        this.btnClear.setFont(fntButton);
        GDStashFrame.setMnemonic(this.btnClear, "MNC_CLEAR");
        if (this.pnlAndOr == null) {
            this.pnlAndOr = new SelectAndOrPane();
        } else {
            this.pnlAndOr.adjustUI();
        }
        if (this.pnlItem == null) {
            this.pnlItem = new ItemFullSelectionPane(this.mode, this.soulboundDefault, this.soulboundEnabled);
        } else {
            this.pnlItem.adjustUI();
        }
        if (this.pnlDamage == null) {
            this.pnlDamage = new DamageSelectionPane();
        } else {
            this.pnlDamage.adjustUI();
        }
        if (this.pnlAttrib == null) {
            this.pnlAttrib = new AttribSelectionPane();
        } else {
            this.pnlAttrib.adjustUI();
        }
        if (this.pnlBonusSkill == null) {
            this.pnlBonusSkill = new SkillBonusPane();
        } else {
            this.pnlBonusSkill.adjustUI();
        }
        if (this.pnlModifiedSkill == null) {
            this.pnlModifiedSkill = new SkillModifierPane();
        } else {
            this.pnlModifiedSkill.adjustUI();
        }
        if (this.pnlItemSkill == null) {
            this.pnlItemSkill = new ItemSkillPane();
        } else {
            this.pnlItemSkill.adjustUI();
        }
        if (this.pnlAffix == null) {
            this.pnlAffix = new AffixPane();
        } else {
            this.pnlAffix.adjustUI();
        }
        if (this.pnlTabbed == null) {
            this.pnlTabbed = new JTabbedPane();
            final JPanel panel = this.buildAttribPanel();
            this.pnlTabbed.add(this.pnlItem);
            this.pnlTabbed.add(this.pnlDamage);
            this.pnlTabbed.add(panel);
        }
        this.pnlTabbed.setTitleAt(0, GDMsgFormatter.getString(GDMsgFormatter.rbUI, "HEADER_SRCH_ITEM_TYPE"));
        this.pnlTabbed.setTitleAt(1, GDMsgFormatter.getString(GDMsgFormatter.rbUI, "HEADER_SRCH_ITEM_DAMAGE"));
        this.pnlTabbed.setTitleAt(2, GDMsgFormatter.getString(GDMsgFormatter.rbUI, "HEADER_SRCH_ITEM_ATTRIB"));
        this.pack();
    }

    private JPanel buildMainPanel() {
        final JPanel panel = new JPanel();
        GroupLayout layout = null;
        GroupLayout.SequentialGroup hGroup = null;
        GroupLayout.SequentialGroup vGroup = null;
        final JPanel pnlButton = this.buildButtonPanel();
        layout = new GroupLayout(panel);
        panel.setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        hGroup = layout.createSequentialGroup();
        hGroup.addGroup(layout.createParallelGroup().addComponent(pnlButton).addComponent(this.pnlTabbed));
        layout.setHorizontalGroup(hGroup);
        vGroup = layout.createSequentialGroup();
        vGroup.addGroup(layout.createParallelGroup().addComponent(pnlButton)).addGroup(layout.createParallelGroup().addComponent(this.pnlTabbed));
        layout.setVerticalGroup(vGroup);
        layout.linkSize(0, pnlButton, this.pnlTabbed);
        return panel;
    }

    private JPanel buildAttribPanel() {
        final JPanel panel = new JPanel();
        GroupLayout layout = null;
        GroupLayout.SequentialGroup hGroup = null;
        GroupLayout.SequentialGroup vGroup = null;
        final JPanel pnlButton = this.buildButtonPanel();
        layout = new GroupLayout(panel);
        panel.setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        hGroup = layout.createSequentialGroup();
        hGroup.addGroup(layout.createParallelGroup().addComponent(this.pnlAttrib).addComponent(this.pnlBonusSkill).addComponent(this.pnlModifiedSkill).addComponent(this.pnlItemSkill).addComponent(this.pnlAffix));
        layout.setHorizontalGroup(hGroup);
        vGroup = layout.createSequentialGroup();
        vGroup.addGroup(layout.createParallelGroup().addComponent(this.pnlAttrib)).addGroup(layout.createParallelGroup().addComponent(this.pnlBonusSkill)).addGroup(layout.createParallelGroup().addComponent(this.pnlModifiedSkill)).addGroup(layout.createParallelGroup().addComponent(this.pnlItemSkill)).addGroup(layout.createParallelGroup().addComponent(this.pnlAffix));
        layout.setVerticalGroup(vGroup);
        layout.linkSize(0, this.pnlAttrib, this.pnlBonusSkill);
        layout.linkSize(0, this.pnlAttrib, this.pnlModifiedSkill);
        layout.linkSize(0, this.pnlAttrib, this.pnlItemSkill);
        layout.linkSize(0, this.pnlAttrib, this.pnlAffix);
        return panel;
    }

    private JPanel buildButtonPanel() {
        final BorderLayout layout = new BorderLayout();
        final JPanel panel = new JPanel();
        panel.setLayout(layout);
        panel.add(this.btnSearch, "Center");
        panel.add(this.btnClear, "West");
        panel.add(this.pnlAndOr, "East");
        return panel;
    }

    public void updateConfig() {
        if (this.pnlItem != null) {
            this.pnlItem.updateConfig();
        }
        if (this.pnlBonusSkill != null) {
            this.pnlBonusSkill.updateBonusSkills();
        }
        if (this.pnlModifiedSkill != null) {
            this.pnlModifiedSkill.updateModifiedSkills();
        }
        if (this.pnlItemSkill != null) {
            this.pnlItemSkill.updateItemSkills();
        }
        if (this.pnlAffix != null) {
            this.pnlAffix.updateAffixes();
        }
    }

    public void clear() {
        this.pnlAndOr.clear();
        this.pnlItem.clear();
        this.pnlDamage.clear();
        this.pnlAttrib.clear();
        this.pnlBonusSkill.clear();
        this.pnlModifiedSkill.clear();
        this.pnlItemSkill.clear();
        this.pnlAffix.clear();
    }

    public void addCriteria(final SelectionCriteria criteria) {
        criteria.selMode = SelectionCriteria.SelectionMode.ITEM;
        this.pnlAndOr.addCriteria(criteria);
        this.pnlItem.addCriteria(criteria);
        this.pnlDamage.addCriteria(criteria);
        this.pnlAttrib.addCriteria(criteria);
        this.pnlBonusSkill.addCriteria(criteria);
        this.pnlModifiedSkill.addCriteria(criteria);
        this.pnlItemSkill.addCriteria(criteria);
        this.pnlAffix.addCriteria(criteria);
    }

    public enum Mode {
        CRAFT,
        SEARCH,
        TRANSFER;
    }

    private class CloseActionListener implements ActionListener {
        @Override
        public void actionPerformed(final ActionEvent e) {
            GDTabbedSearchDialog.this.setVisible(false);
        }
    }

    private class SearchActionListener implements ActionListener {
        @Override
        public void actionPerformed(final ActionEvent e) {
            final GDLog log = new GDLog();
            final SelectionCriteria criteria = new SelectionCriteria();
            GDTabbedSearchDialog.this.addCriteria(criteria);
            criteria.checkCriteria(log);
            if (log.containsErrors()) {
                GDMsgLogger.addLog(log);
                GDMsgLogger.showLog(GDTabbedSearchDialog.this, GDMsgFormatter.getString(GDMsgFormatter.rbMsg, "ERR_SEARCH"));
                return;
            }
            GDTabbedSearchDialog.this.setCursor(Cursor.getPredefinedCursor(3));
            if (GDTabbedSearchDialog.this.uiSearch != null) {
                GDTabbedSearchDialog.this.uiSearch.search(criteria);
            }
            GDTabbedSearchDialog.this.setVisible(false);
            GDTabbedSearchDialog.this.setCursor(Cursor.getDefaultCursor());
        }
    }

    private class ClearActionListener implements ActionListener {
        @Override
        public void actionPerformed(final ActionEvent e) {
            GDTabbedSearchDialog.this.clear();
        }
    }
}
